package cn.edu.nju.software.filter;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import cn.edu.nju.software.util.Constants;
import cn.edu.nju.software.util.PreferencesOperator;

public class LoginFilter implements Filter {
	
	String[] requireLoginPath;
	String indexPagePath, loginPagePath, frontLoginPostUrl, backNamespace, backLoginPostUrl;

	@Override
	public void init(FilterConfig config) throws ServletException {
		WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(config.getServletContext());
		PreferencesOperator preferencesOperator = (PreferencesOperator) applicationContext.getBean("preferencesOperator");
		String[] keys = new String[] {
				Constants.REQUIRE_LOGIN_PATH, 
				Constants.INDEX_PAGE_PATH, 
				Constants.LOGIN_PAGE_PATH, 
				Constants.FRONT_LOGIN_POST_URL, 
				Constants.BACK_NAMESPACE, 
				Constants.BACK_LOGIN_POST_URL};
		String[] values = preferencesOperator.getProperties(keys);
		requireLoginPath = values[0].split(",");
		indexPagePath = values[1];
		loginPagePath = values[2];
		frontLoginPostUrl = values[3];
		backNamespace = values[4];
		backLoginPostUrl = values[5];
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest)request;
		HttpServletResponse httpResponse = (HttpServletResponse)response;
		HttpSession session = httpRequest.getSession();
		String servletPath = httpRequest.getServletPath();
		String contextPath = httpRequest.getContextPath();
		
		if (servletPath.contains(backNamespace+"/")) {									//如果是后台路径
			if (session.getAttribute(Constants.SESSION_ADMIN) == null) {					//如果未登陆
				if (servletPath.equals(backNamespace+loginPagePath) || servletPath.equals(backNamespace+backLoginPostUrl)) {
					chain.doFilter(request, response);
				} else {																		//并非登录则跳转到登陆页
					httpResponse.sendRedirect(contextPath + backNamespace + loginPagePath);
				}
			} else {																		//如果已登陆
				if (servletPath.equals(backNamespace+loginPagePath) || servletPath.equals(backNamespace+backLoginPostUrl)) {
					httpResponse.sendRedirect(contextPath + backNamespace + indexPagePath);
				} else {																		//并非登录则不予拦截
					chain.doFilter(request, response);
				}
			}
		} else {																		//如果是前台路径
			if (session.getAttribute(Constants.SESSION_USER) == null) {						//如果未登陆
				if (!servletPath.equals(loginPagePath)) {
					session.setAttribute(Constants.SESSION_URL, servletPath.substring(1));		//保存登录前的URL
				}
				if (requireLogin(servletPath)) {												//如果打开的页面需要登录，则跳到登录页
					//保存登录前的表单参数
					Enumeration<String> parameterNames = httpRequest.getParameterNames();
					StringBuilder pNames = new StringBuilder("[");
					StringBuilder pValues = new StringBuilder("[");
					while (parameterNames.hasMoreElements()) {
						String parameter = parameterNames.nextElement();
						pNames.append("\"").append(parameter).append("\"").append(",");
						pValues.append("\"").append(httpRequest.getParameter(parameter)).append("\"").append(",");
					}
					session.setAttribute(Constants.SESSION_PARAMETER_NAMES, pNames.substring(0, pNames.length()-1)+"]");
					session.setAttribute(Constants.SESSION_PARAMETER_VALUES, pValues.substring(0, pValues.length()-1)+"]");
					httpResponse.sendRedirect(contextPath + loginPagePath);
				} else {																		//否则不予拦截
					chain.doFilter(request, response);
				}
			} else {																		//如果已登陆
				if (servletPath.equals(loginPagePath) || servletPath.equals(frontLoginPostUrl)) {
					httpResponse.sendRedirect(contextPath + indexPagePath);
				} else {																		//并非登录则不予拦截
					chain.doFilter(request, response);
				}
			}
		}
	}
	
	@Override
	public void destroy() {
	}
	
	private boolean requireLogin(String path) {
		for (String s : requireLoginPath) {
			if (path.equals(s)) {
				return true;
			}
		}
		return false;
	}

}
